package com.excel.common;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.excel.config.CustomCellWriteHandler;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/4/18 15:29
 * @since JDK 1.8
 */
public class ExcelUtils {


    /**
     * 项目通用的Excel数据导出工具
     * @param name
     * @param objectMaps
     * @param stringStringMap
     * @return
     */
    public static String commonExcelMapList(String name,List<Map<String,Object>> objectMaps,Map<String, String> stringStringMap){
        String path=System.getProperty("user.dir");
        String excelName=String.valueOf(System.currentTimeMillis());
        String realPath=path+ File.separator+"excel"+File.separator+name+excelName+".xlsx";
        formartExcelMapListHead(realPath,objectMaps,stringStringMap);
        return realPath;
    }
    /**
     *动态头部
     * @param path  路径
     * @param objectMaps 数据集合
     * @param stringObjectMap  要做字段转换的Map
     */
    public static  void  formartExcelMapListHead(String path, List<Map<String, Object>> objectMaps, Map<String,String> stringObjectMap){
        if(objectMaps==null||objectMaps.size()==0){
            return;
        }
        List<List<String>> headList = new ArrayList<List<String>>();
        Map<String, Object> map=objectMaps.get(0);
        Set<String> strings=map.keySet();
        for (String key:strings){
            List<String> stringList=new ArrayList<>(1);
            String headName=null;
            if (stringObjectMap.containsKey(key)){
                headName=stringObjectMap.get(key);
            }else {
                headName=key;
            }
            stringList.add(headName);
            headList.add(stringList);
        }
        List<List<Object>> list = new ArrayList<>();
        for (int i = 0; i < objectMaps.size() ; i++) {
            List<Object> objects=new ArrayList<>(strings.size());
            Map<String, Object> objectMap1=objectMaps.get(i);
            for (String string: strings) {
                Object v=objectMap1.get(string);
                objects.add(v);
            }
            list.add(objects);
        }
        ExcelWirte(path,headList,list);
    }

    /**
     * 通用Map<String,Object>
     * @param path
     * @param objectMap
     */
    public static void FormartExcelMapData(String path,List<Map<String, Object>> objectMap){
        if(objectMap==null||objectMap.size()==0){
            return;
        }
        Map<String, Object> map=objectMap.get(0);
        List<List<String>> headList = new ArrayList<List<String>>();
        Set<String> strings=map.keySet();
        for (String key:strings){
            List<String> stringList=new ArrayList<>(1);
            stringList.add(key);
            headList.add(stringList);
        }
        List<List<Object>> list = new ArrayList<>();
        for (int i = 0; i < objectMap.size() ; i++) {
            List<Object> objects=new ArrayList<>(strings.size());
            Map<String, Object> objectMap1=objectMap.get(i);
            for (String string: strings) {
                Object v=objectMap1.get(string);
                objects.add(v);
            }
            list.add(objects);
        }
        ExcelWirte(path,headList,list);
    }


    /**
     * 通用bean
     * @param path
     * @param tList
     * @param <T>
     */
    public static <T> void formartExcelLiatBean(String path,List<T> tList){
        if(tList==null||tList.size()==0){
            return;
        }
        T t=tList.get(0);
        Class<T> cls=(Class<T>)t.getClass();
        Field[] fields=cls.getDeclaredFields();
        //添加头部集合
        List<List<String>> headList = new ArrayList<List<String>>();
        for (int i = 0; i < fields.length; i++) {
            Field field=fields[i];
            fields[i].setAccessible(true);
            String headName=null;
            if(field.isAnnotationPresent(ExcelProperty.class)){
                ExcelProperty excelProperty=field.getAnnotation(ExcelProperty.class);
                headName= excelProperty.value()[0];
            }else {
                headName=field.getName();
            }
            List<String> head=new ArrayList<>(1);
            head.add(headName);
            headList.add(head);
        }
        try {
            List<List<Object>> list = new ArrayList<>();
            for (int i = 0; i < tList.size(); i++) {
                List<Object> objects=new ArrayList<>(fields.length);
                T object=tList.get(i);
                for (int j = 0; j <fields.length ; j++) {
                    fields[j].setAccessible(true);
                    Object value=fields[j].get(object);
                    objects.add(value);
                }
                list.add(objects);
            }
            ExcelWirte(path,headList,list);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void ExcelWirte(String path,List<List<String>> headList,List<List<Object>> list){
        EasyExcel.write(path)
                // 这里放入动态头
                .head(headList).sheet("模板")
                .registerWriteHandler(new CustomCellWriteHandler())
                // 当然这里数据也可以用 List<List<String>> 去传入
                .doWrite(list);
        // 记得 释放资源
    }

}
